home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Experimental BBS Explossion 3
/
Experimental BBS Explossion III.iso
/
c
/
pcw.zip
/
TMENU.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-17
|
16KB
|
372 lines
/**********************************************************/
/* File Id. Tmenu.C */
/* Author. Chris Balthrop */
/* from Lmenu.c by Stan Milam. */
/* Date Written. 09oct91 */
/* */
/* */
/* Comments: The routines in this file allow the creation*/
/* and use of Top line style menus. Moreover, more than */
/* one Top menu per window is allowed. More than one menu */
/* can be stacked into one window. The Mouse can be used */
/* to make selection and scroll the menus or the arrow & */
/* PgDn/PgUp keys can be used. Home & End keys move to */
/* first and last menus respectively. */
/**********************************************************/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#include "pcw.i"
#include "pcwproto.h"
#include "keys.h"
#include "menu.h"
#define MSGROW 2
#define ITEMROW 1
/* Prototype the internal functions */
static void change_menu(TMNUTYPE *menu);
static void change_bar_pos(TMNUTYPE *menu, int crnt_bar);
static int search_menu(TMNUTYPE *menu, int select_char);
static int search_mouse_select(TMNUTYPE *menu, int col);
static int get_max_bars(TMNUFLDS *ttmp);
/***********************************************************/
/* Maketmenu */
/* */
/* This function when invoked will draw the Top style menu */
/* pointed to by *menu. See the TMNUTYPE definition in */
/* menu.h. */
/***********************************************************/
WNDPTR *maketmenu(TMNUTYPE *menu) {
MENU_WND *twnd; /* Pointer to menu window */
twnd = &menu->twnd; /* Establish adressablity */
setborder(twnd->btype); /* Set borders & colors */
titlecolor(twnd->tfclr, twnd->tbclr);
bordercolor(twnd->bfclr, twnd->bbclr);
/* Frame the menu window and store handle in menu structure */
twnd->wnd = wframe(twnd->urow, twnd->ucol,
twnd->lrow, twnd->lcol,
twnd->fcolor, twnd->bcolor);
/* Check to see of okay */
if (twnd->wnd == NULL) return(NULL);
/* Wframe may have adjusted boundries */
twnd->urow = twnd->wnd->urow;
twnd->ucol = twnd->wnd->ucol;
twnd->lrow = twnd->wnd->lrow;
twnd->lcol = twnd->wnd->lcol;
/* Draw the arrows */
qputchar(twnd->urow+1,twnd->ucol,twnd->bfclr,twnd->bbclr,24);
qputchar(twnd->urow+1,twnd->lcol,twnd->bfclr,twnd->bbclr,25);
/* Title wnd, Fill window with menu contents & return */
wtitle(twnd->wnd, twnd->tvloc, twnd->thloc, twnd->title);
change_menu(menu);
return(twnd->wnd);
}
/***********************************************************/
/* TmenuInput */
/* */
/* When invoked will manipulate Top style menu. Returns */
/* the select_key in the TMNUFLDS. */
/***********************************************************/
int tmenuinput(TMNUTYPE *menu) {
TMNUFLDS *ttmp, **stmp; /* Pointers to menus */
MENU_WND *twnd; /* Pointer the menu parms */
int ch; /* For keyin() function */
int max_bars, max_menus; /* How many menus & bars */
int crnt_wnd, crnt_bar; /* Keep track menus & bars */
int row, col, bstatus; /* For Mouse */
stmp = (TMNUFLDS **) menu->tlist;
ttmp = stmp[menu->wnd_pos]; /* Get address of 1st menu */
twnd = &menu->twnd; /* Get address of wnd parms */
if (mpresent) hide_mouse(); /* Turn the mouse off so */
re_order(twnd->wnd,NORMAL); /* We can reorder the windows */
if (mpresent) show_mouse(); /* And finally turn it on */
for (max_menus = 0;stmp[max_menus] != NULL;max_menus++);
max_menus--; /* and adjust */
max_bars = get_max_bars(ttmp); /* Get # selects this menu */
if (mpresent) show_mouse(); /* Turn on the mouse */
for(;;) { /* Loop forever */
crnt_bar = menu->bar_pos; /* Track current bar pos */
crnt_wnd = menu->wnd_pos; /* And menu position */
ch = keyin();
switch (ch) { /* Which one? */
case ENTER : /* Selects bar pos */
case BOTH_MOUSE_KEY :
return(ttmp[menu->bar_pos].select_key);
case RITE_MOUSE_KEY :
if (menu->wnd_pos == 0) break;
menu->bar_pos = menu->wnd_pos = 0;
change_menu(menu);
ttmp = stmp[0];
max_bars = get_max_bars(ttmp);
break;
case LEFT_MOUSE_KEY :
get_mpos(&row, &col, &bstatus);
if (row == twnd->wnd->urow+1) { /* Select row? */
/* If hot spot */
if (search_mouse_select(menu, col)) {
change_bar_pos(menu,crnt_bar); /* Change */
/* return */
return(ttmp[menu->bar_pos].select_key);
}
else {
if (col == twnd->wnd->ucol) { /* Up arrow? */
menu->wnd_pos--; /* Decrement menu index */
if (menu->wnd_pos < 0) /* Check if okay */
/* No - last menu */
menu->wnd_pos = max_menus;
menu->bar_pos = 0; /* First bar pos */
change_menu(menu); /* Next menu */
/* Address new menu */
ttmp = stmp[menu->wnd_pos];
/* # bars new menu */
max_bars = get_max_bars(ttmp);
}
else { /* Down arrow */
if (col == twnd->wnd->lcol) {
menu->wnd_pos++;
if (stmp[menu->wnd_pos] == NULL)
menu->wnd_pos = 0;
menu -> bar_pos = 0;
change_menu(menu);
ttmp = stmp[menu->wnd_pos];
max_bars = get_max_bars(ttmp);
}
}
}
}
break;
case LEFTARROW : /* Prev bar pos */
case SHFTTAB :
menu->bar_pos--;
if (menu->bar_pos < 0) /* Check if < 0 */
menu->bar_pos = max_bars; /* Set to max bar */
change_bar_pos(menu, crnt_bar); /* Change bar pos */
break;
case RITEARROW : /* Next bar position */
case TAB :
menu->bar_pos++; /* Bump & check */
if (ttmp[menu->bar_pos].select_key == 0)
menu->bar_pos = 0; /* First one if at end */
change_bar_pos(menu, crnt_bar); /* Change bars */
break;
case UPARROW : /* Prev Menu */
case PGUP:
if (max_menus == 0) break;
menu->wnd_pos--; /* Decrement menu index */
if (menu->wnd_pos < 0) menu->wnd_pos = max_menus;
menu->bar_pos = 0; /* Set bar index to first */
change_menu(menu); /* Put out new menu */
ttmp = stmp[menu->wnd_pos]; /* Address new menu */
max_bars = get_max_bars(ttmp); /* Count selections */
break;
case DOWNARROW : /* Next menu */
case PGDN:
if (max_menus == 0) break;
menu->wnd_pos++; /* Bump menu index */
if (stmp[menu->wnd_pos] == NULL) /* See if at end */
menu->wnd_pos = 0; /* And set to first */
menu->bar_pos = 0; /* First bar of menu */
change_menu(menu); /* Put out new menu */
ttmp = stmp[menu->wnd_pos]; /* Address new menu */
max_bars = get_max_bars(ttmp);/* Count the selects */
break;
case HOME : /* First menu */
case ESC :
if (menu->wnd_pos == 0) break;
menu->bar_pos = menu->wnd_pos = 0;
change_menu(menu);
ttmp = stmp[0];
max_bars = get_max_bars(ttmp);
break;
case END: /* Last Menu */
if (menu->wnd_pos == max_menus) break;
menu->bar_pos = 0;
menu->wnd_pos = max_menus;
change_menu(menu);
ttmp = stmp[menu->wnd_pos];
max_bars = get_max_bars(ttmp);
break;
default :
if (search_menu(menu, ch)) { /* Search for select match */
if (crnt_wnd != menu->wnd_pos) { /* In another menu? */
change_menu(menu); /* Put out new menu */
ttmp = stmp[menu->wnd_pos]; /* Address new menu */
return(ttmp[menu->bar_pos].select_key); /* Return */
}
if (crnt_bar != menu->bar_pos) { /* Same menu,dif bar */
change_bar_pos(menu, crnt_bar); /* Chg bar pos */
return(ttmp[menu->bar_pos].select_key); /* Return */
}
else /* Must be crnt bar so return */
return(ttmp[menu->bar_pos].select_key);
}
}
}
#ifndef __TURBOC__
return 0;
#endif
}
/***********************************************************/
/* Change_Menu */
/* */
/* When invoked puts menu pointed to by menu->wnd_pos in */
/* the window. Bar position is determined by menu->bar_pos*/
/***********************************************************/
static void change_menu(TMNUTYPE *menu) {
int tcv1, col, length;
TMNUFLDS *ttmp, **stmp;
MENU_WND *twnd;
twnd = &menu->twnd;
stmp = (TMNUFLDS **) menu->tlist;
ttmp = stmp[menu->wnd_pos];
if (mpresent) hide_mouse();
clr_wnd(twnd->wnd, 1);
for (tcv1 = 0; ttmp[tcv1].select_key != (char) NULL; tcv1++)
wputs(twnd->wnd, ITEMROW, ttmp[tcv1].select_col, ttmp[tcv1].item);
col = ttmp[menu->bar_pos].select_col;
length = strlen(ttmp[menu->bar_pos].item);
w_chg_attr(twnd->wnd,ITEMROW, col, twnd->cfclr, twnd->cbclr, length);
if (mpresent) show_mouse();
}
/***********************************************************/
/* Search_Menu */
/* */
/* Searches thru all menus looking for a select_key match */
/* with keyboard input. All characters are converted to */
/* upper case. Returns non-zero if found. Zero if not */
/* found. If a match is found the menu index and bar index*/
/* are changed to point to the selected item. */
/***********************************************************/
static int search_menu(TMNUTYPE *menu, int select_char) {
TMNUFLDS *ttmp, **stmp; /* Menu Pointers */
int tcv1, tcv2, ch; /* Index variables */
stmp = (TMNUFLDS **) menu->tlist; /* Address menu lists */
select_char = toupper(select_char); /* Uppercase keybd input */
for (tcv1 = 0; stmp[tcv1] != NULL; tcv1++) { /* Get the menu list */
ttmp = stmp[tcv1]; /* One menu list at a time */
for (tcv2 = 0; ttmp[tcv2].select_key != (char) NULL; tcv2++) {
/* Uppercase select_key */
ch = (char) toupper(ttmp[tcv2].select_key);
if (ch == select_char) { /* Do they match ? */
menu->bar_pos = tcv2; /* Set bar index */
menu->wnd_pos = tcv1; /* Set menu index */
return(1); /* Return TRUE */
}
}
}
return (0); /* No matches */
}
/**********************************************************/
/* Search_Mouse_Select */
/* */
/* Runs through all items in a menu to determine if the */
/* rat was on the item. If a match is found the bar index*/
/* is updated to reflect the selected item and we return */
/* a non-zero return code to indicate a match was found. */
/**********************************************************/
static int search_mouse_select(TMNUTYPE *menu, int col) {
MENU_WND *twnd;
TMNUFLDS *ttmp, **stmp;
int tcv, item_len, item_col;
twnd = &menu->twnd; /* Establish Addressability */
stmp = (TMNUFLDS **) menu->tlist;
ttmp = stmp[menu->wnd_pos];
/* If inside the window determine column in the window */
if (col > twnd->wnd->ucol) col -= twnd->wnd->ucol;
else return(0); /* Otherwise not in window so exit */
/* Search thru all items in list */
for (tcv = 0; ttmp[tcv].select_key != 0; tcv++) {
/* Get items column */
item_col = ttmp[tcv].select_col;
/* Determine its length on the screen */
item_len = (item_col + strlen(ttmp[tcv].item)) - 1;
/* If mouse on the item */
if (col >= item_col && col <= item_len) {
menu->bar_pos = tcv; /* Set the bar index */
return(1); /* Return True */
}
}
return(0); /* No match found */
}
/**********************************************************/
/* Change_Bar_Pos */
/* */
/* Changes the bar position in the window by changing the */
/* attribute of the current bar to normal window attribute*/
/* and changing the attribute of the new item to the color*/
/* specified for bar color. Got it. Okay, test in five */
/* minutes! */
/**********************************************************/
static void change_bar_pos(TMNUTYPE *menu, int crnt_bar) {
int col, length;
TMNUFLDS *ttmp, **stmp;
MENU_WND *twnd;
twnd = &menu->twnd; /* Establish addressability */
stmp = (TMNUFLDS **) menu->tlist;
ttmp = stmp[menu->wnd_pos];
if (mpresent) hide_mouse(); /* If rat home hide from neighbors! */
/* Get len and col of item on scrn and change color attribute */
length = strlen(ttmp[crnt_bar].item);
col = ttmp[crnt_bar].select_col;
w_chg_attr(twnd->wnd,ITEMROW,col,twnd->fcolor,twnd->bcolor,length);
/* Change new item color attribute */
length = strlen(ttmp[menu->bar_pos].item);
col = ttmp[menu->bar_pos].select_col;
w_chg_attr(twnd->wnd,ITEMROW,col, twnd->cfclr, twnd->cbclr,length);
if (mpresent) show_mouse(); /* Finally turn back on the mouse */
}
/**********************************************************/
/* Get_Max_Bars */
/* */
/* Used to count how many selections for a given menu. */
/**********************************************************/
static int get_max_bars(TMNUFLDS *ttmp) {
int i;
for (i = 0; ttmp[i].select_key != 0; i++); i--;
return(i);
}